package com.itdl.lock.config;

import com.itdl.cache.config.CustomRedisConfig;
import com.itdl.cache.manager.CacheNullValuesHandle;
import com.itdl.common.base.properties.CustomRedisProperties;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.CollectionUtils;

import java.util.Set;

/**
 * Redis实现分布式锁的配置（使用Redisson）
 */
@Configuration  // 标识为一个配置项，注入Spring容器
@AutoConfigureBefore({CustomRedisConfig.class, CacheNullValuesHandle.class})
@ConditionalOnProperty(value = "redis.enable", havingValue = "true")    // 开启redis.enable=true时生效
@Slf4j
public class RedisLockConfig {

    private volatile boolean isCluster = false;

    private volatile String redisHostsStr = "";

    @Bean
    @ConditionalOnMissingBean
    public RedissonClient redissonClient(CustomRedisProperties redisProperties){
        // 构建配置
        Config config =  buildConfig(redisProperties);

        RedissonClient redissonClient = Redisson.create(config);
        log.info("==============创建redisClient{}版成功：{}==================", isCluster ? "集群": "单机", redisHostsStr);
        return redissonClient;
    }

    private Config buildConfig(CustomRedisProperties redisProperties) {
        final Config config = new Config();
        // 根据逗号切割host列表
        Set<String> hosts = org.springframework.util.StringUtils.commaDelimitedListToSet(redisProperties.getHost());
        if (CollectionUtils.isEmpty(hosts)){
            throw new RuntimeException("redis host address cannot be empty");
        }
        // 只有一个host, 表示是单机host
        if (hosts.size() == 1){
            String hostPort = hosts.stream().findFirst().get();
            redisHostsStr = "redis://" + hostPort.trim();
            config.useSingleServer()
                    .setAddress(redisHostsStr)
                    .setDatabase(redisProperties.getDatabase())
                    .setPassword(StringUtils.isBlank(redisProperties.getPassword()) ? null : redisProperties.getPassword())
            ;
            isCluster = false;
        }else {
            // 集群处理
            String[] redisHosts = new String[hosts.size()];
            int i = 0;
            for (String host : hosts) {
                String[] split = host.split(":");
                if (split.length != 2){
                    throw new RuntimeException("host or port err");
                }
                redisHosts[i] = "redis://" + host.trim();
                i++;
            }
            redisHostsStr = String.join(",", redisHosts);
            // 配置集群
            config.useClusterServers()
                    .addNodeAddress(redisHosts)
                    .setPassword(StringUtils.isBlank(redisProperties.getPassword()) ? null : redisProperties.getPassword())
                    // 解决Not all slots covered! Only 10922 slots are available
                    .setCheckSlotsCoverage(false);
            isCluster = true;
        }

        return config;
    }
}

